package com.zytlifeservice.service.pay;

import com.qianmi.open.api.ApiException;
import com.qianmi.open.api.domain.elife.AdminItem;
import com.qianmi.open.api.domain.elife.ItemProp;
import com.qianmi.open.api.domain.elife.WaterCoalBill;
import com.qianmi.open.api.request.BmDirectRechargeLifeRechargePayBillRequest;
import com.qianmi.open.api.request.BmDirectRechargeWaterCoalGetAccountInfoRequest;
import com.qianmi.open.api.request.BmDirectRechargeWaterCoalItemListRequest;
import com.qianmi.open.api.request.BmDirectRechargeWaterCoalItemPropsListRequest;
import com.qianmi.open.api.response.BmDirectRechargeLifeRechargePayBillResponse;
import com.qianmi.open.api.response.BmDirectRechargeWaterCoalGetAccountInfoResponse;
import com.qianmi.open.api.response.BmDirectRechargeWaterCoalItemListResponse;
import com.qianmi.open.api.response.BmDirectRechargeWaterCoalItemPropsListResponse;
import com.zytlifeservice.domain.User;
import com.zytlifeservice.domain.pay.AlipayOrder;
import com.zytlifeservice.domain.pay.BaseQmOrder;
import com.zytlifeservice.domain.pay.WaterCoalOrder;
import com.zytlifeservice.domain.pay.WxPayOrder;
import com.zytlifeservice.exception.UserException;
import com.zytlifeservice.repository.UserRepository;
import com.zytlifeservice.repository.pay.AlipayOrderRepository;
import com.zytlifeservice.repository.pay.WaterCoalOrderRepository;
import com.zytlifeservice.repository.pay.WxPayOrderRepository;
import com.zytlifeservice.response.pay.QueryInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

/**
 * Created by MJS on 2017/6/1.
 */
@Service
public class WaterCoalService {

    //后期封装进spring容器内，保证单例

    private static final Logger logger = LoggerFactory.getLogger(WaterCoalService.class);
    @Autowired
    PublicService publicService;

    @Autowired
    AlipayService alipayService;

    @Autowired
    WxPayService wxPayService;

    @Autowired
    UserRepository userRepository;

    @Autowired
    WaterCoalOrderRepository waterCoalOrderRepository;

    @Autowired
    AlipayOrderRepository alipayOrderRepository;

    @Autowired
    WxPayOrderRepository wxPayOrderRepository;


    public List<AdminItem> queryInfoByAddress(String address, int type) {
        logger.error("!WaterCoalOrder.TYPE_WATER.equals(type)={}", (!WaterCoalOrder.TYPE_WATER.equals(type)));
        String orderType = "";
        switch (type) {
            case AlipayOrder.TYPE_WATER:
                orderType = WaterCoalOrder.TYPE_WATER;
                break;

            case AlipayOrder.TYPE_ELECTRIC:
                orderType = WaterCoalOrder.TYPE_ELECTRIC;
                break;

            case AlipayOrder.TYPE_COAL:
                orderType = WaterCoalOrder.TYPE_COAL;
                break;

            default:
                throw new UserException("类型错误", 303);
        }
        BmDirectRechargeWaterCoalItemListRequest req = new BmDirectRechargeWaterCoalItemListRequest();
        req.setProjectId(orderType);
        req.setItemName(address);
        try {
            BmDirectRechargeWaterCoalItemListResponse response = publicService.execute(req);
            if (response.isSuccess()) {
                List<AdminItem> items = response.getItems();
                if (items != null && items.size() > 0) {
                    parseItems(items);
                    return items;
                } else {
                    throw new UserException(address + "尚未支持该服务", 1);
                }
            }
        } catch (ApiException e) {
            e.printStackTrace();
        }
        throw new UserException("查询失败", 303);
    }

    private void parseItems(List<AdminItem> items) {
        for (AdminItem item : items) {
            String[] split = item.getItemName().replaceAll("\\s{1,}", " ").split(" ");
            if (split.length == 1) {
                String rs = split[0].replace("直充任意充", "");
                rs = rs.replace("户号", "");
                item.setItemName(rs);
            } else {
                item.setItemName(split[1]);
            }
        }
    }

    public Object queryItemInfo(String itemId, String account) {
        //查询账户分2步。 1。根据itemId查询商品详细信息
        BmDirectRechargeWaterCoalItemPropsListRequest req = new BmDirectRechargeWaterCoalItemPropsListRequest();
        req.setItemId(itemId);
        try {
            BmDirectRechargeWaterCoalItemPropsListResponse response = publicService.execute(req);
            if (response.isSuccess()) {
                QueryInfo queryInfo = parseQueryInfo(response, account);
                //2. 根据详细信息获取账户信息。
                return queryAccountInfo(queryInfo);
            }
        } catch (ApiException e) {
            e.printStackTrace();
        }
        throw new UserException("查询失败", 304);
    }

    private QueryInfo parseQueryInfo(BmDirectRechargeWaterCoalItemPropsListResponse response, String account) {
        QueryInfo queryInfo = new QueryInfo();
        queryInfo.setItemId(response.getItemId());
        queryInfo.setAccount(account);
        queryInfo.setProjectId(response.getCid());

        for (ItemProp itemProp : response.getItemProps()) {
            String type = itemProp.getType();
            if ("BRAND".equals(type)) {
//                unitId	String	必须	v83589		缴费单位V编号(属性查询接口中返回的参数itemProps-"type": "BRAND"下的vid)
                queryInfo.setUnitId(itemProp.getVid());
//                unitName	String	必须	南京市水费		缴费单位名称(属性查询接口中返回的参数itemProps-"type": "BRAND"下的vname)
                queryInfo.setUnitName(itemProp.getVname());
            } else if ("PRVCIN".equals(type)) {
//            province	String	必须	江苏		省名称(后面不带"省"，属性查询接口中返回的参数itemProps-"type": "PRVCIN"下的vname)
                queryInfo.setProvince(itemProp.getVname());
            } else if ("CITYIN".equals(type)) {
//            city	String	必须	南京		市名称(后面不带"市"，属性查询接口中返回的参数itemProps-"type": "CITYIN"下的vname)
                queryInfo.setCity(itemProp.getVname());
//            cityId  String	必须	v2058		城市V编号(属性查询接口中返回的参数itemProps-"type": "CITYIN"下的vid)
                queryInfo.setCityId(itemProp.getVid());
            } else if ("SPECIAL".equals(type)) {
//            modeId	String	必须	v2621		缴费方式V编号 (属性查询接口中返回的参数itemProps-"type": "SPECIAL"下的vid)
                queryInfo.setModeId(itemProp.getVid());
            }
        }
        logger.error("查询解析的结果={}", queryInfo);
        return queryInfo;
    }

    public Object queryAccountInfo(QueryInfo queryInfo) {
        BmDirectRechargeWaterCoalGetAccountInfoRequest req = new BmDirectRechargeWaterCoalGetAccountInfoRequest();
        req.setItemId(queryInfo.getItemId());
        req.setAccount(queryInfo.getAccount());
        req.setProjectId(queryInfo.getProjectId());
        req.setUnitId(queryInfo.getUnitId());
        req.setProvince(queryInfo.getProvince());
        req.setCity(queryInfo.getCity());
        req.setUnitName(queryInfo.getUnitName());
        req.setCityId(queryInfo.getCityId());
        req.setModeId(queryInfo.getModeId());
        try {
            logger.info("请求account");
            BmDirectRechargeWaterCoalGetAccountInfoResponse response = publicService.execute(req);
            logger.info("请求结束");
            if (response.isSuccess()) {
                //这里封装好返回的结果。
                if (response.getStatus().equals("0")) {
                    //如果没有结果返回，即查询时未欠费的情况
                    String errorMsg = response.getMessage();
                    if ("未查询到用户信息".equals(errorMsg)) {  //这里后期变化
                        throw new UserException("该地区尚未提供查询服务，有待添加", 2);
                    } else {
                        throw new UserException(errorMsg, 1);
                    }
                } else if (response.getStatus().equals("1")) {
                    AccountInfo accountInfo = new AccountInfo();
                    WaterCoalBill waterCoalBill = response.getWaterCoalBills().get(0);
                    accountInfo.setCustomerAddress(waterCoalBill.getCustomerAddress());
                    accountInfo.setCustomerName(waterCoalBill.getCustomerName());
                    accountInfo.setPayAmount(waterCoalBill.getPayAmount());
                    return accountInfo;
                }
            }
        } catch (ApiException e) {
            e.printStackTrace();
        }
        throw new UserException("查询失败", 303);
    }


    private QueryInfo getQueryInfo(List<ItemProp> itemProps) {
        QueryInfo queryInfo = new QueryInfo();
        //顺序改变一下。按着结果来倒推。
        for (ItemProp itemProp : itemProps) {
            String type = itemProp.getType();
            if ("BRAND".equals(type)) {
//                unitId	String	必须	v83589		缴费单位V编号(属性查询接口中返回的参数itemProps-"type": "BRAND"下的vid)
                queryInfo.setUnitId(itemProp.getVid());
//                unitName	String	必须	南京市水费		缴费单位名称(属性查询接口中返回的参数itemProps-"type": "BRAND"下的vname)
                queryInfo.setUnitName(itemProp.getVname());

            } else if ("PRVCIN".equals(type)) {
//            province	String	必须	江苏		省名称(后面不带"省"，属性查询接口中返回的参数itemProps-"type": "PRVCIN"下的vname)
                queryInfo.setProvince(itemProp.getVname());
            } else if ("CITYIN".equals(type)) {
//            city	String	必须	南京		市名称(后面不带"市"，属性查询接口中返回的参数itemProps-"type": "CITYIN"下的vname)
                queryInfo.setCity(itemProp.getVname());
//            cityId  String	必须	v2058		城市V编号(属性查询接口中返回的参数itemProps-"type": "CITYIN"下的vid)
                queryInfo.setCityId(itemProp.getVid());
            } else if ("SPECIAL".equals(type)) {
//            modeId	String	必须	v2621		缴费方式V编号 (属性查询接口中返回的参数itemProps-"type": "SPECIAL"下的vid)
                queryInfo.setModeId(itemProp.getVid());
            }
        }
        return queryInfo;
    }


    public String[] preCreateOrder(String itemId, String itemName, String address, String rechargeAmount, String account, int type, Long userId) {
        String[] res = new String[2];
        User one = userRepository.findOne(userId);
        if (one == null) {
            throw new UserException("用户不存在", 202);
        }
        String orderType = "";
        switch (type) {
            case AlipayOrder.TYPE_WATER:
                orderType = WaterCoalOrder.TYPE_WATER;
                break;

            case AlipayOrder.TYPE_ELECTRIC:
                orderType = WaterCoalOrder.TYPE_ELECTRIC;
                break;

            case AlipayOrder.TYPE_COAL:
                orderType = WaterCoalOrder.TYPE_COAL;
                break;

            default:
                throw new UserException("类型错误", 303);
        }
        //生成aliOrder
        AlipayOrder alipayOrder = new AlipayOrder();
        alipayOrder.setStoreId(one.getStoreId());
        alipayOrder.setSubject(itemName);//对应的后台的信息
        String outTradeNo = "zyt" + userId + System.currentTimeMillis()   //添加userId
                + (long) (Math.random() * 10000000L);
        alipayOrder.setOutTradeNo(outTradeNo);
        alipayOrder.setTotalAmount(rechargeAmount);
        alipayOrder.setUserId(userId);
        int aliType = AlipayOrder.TYPE_WATER;

        if (WaterCoalOrder.TYPE_WATER.equals(type)) {
            aliType = AlipayOrder.TYPE_WATER;
        } else if (WaterCoalOrder.TYPE_COAL.equals(type)) {
            aliType = AlipayOrder.TYPE_COAL;
        } else if (WaterCoalOrder.TYPE_ELECTRIC.equals(type)) {
            aliType = AlipayOrder.TYPE_ELECTRIC;
        }

        alipayOrder.setType(aliType);
        alipayOrderRepository.save(alipayOrder);

        WaterCoalOrder order = new WaterCoalOrder();
        order.setRechargeAccount(account);
        order.setAddress(address);
        order.setItemId(itemId);
        order.setOutTradeNo(outTradeNo);
        order.setItemName(itemName);  //联通话费+充值金额
        order.setUserId(userId);
        order.setPayType(BaseQmOrder.PAY_TYPE_ALIPAY);
        order.setSaleAmount(rechargeAmount);
        order.setType(orderType);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        order.setOrderTime(sdf.format(new Date()));
        order.setPayState("0");  //这里修改其状态。
        order.setPayResult(BaseQmOrder.STATUS_INIT);
        if (!publicService.querySum(rechargeAmount)) {
            order.setFailReason("直销商余额不足,取消支付宝预下单");
            waterCoalOrderRepository.save(order);
            res[0] = "fail";
            res[1] = "直销商余额不足,取消支付宝预下单";
            return res;
        }
        publicService.setBaseOrderType(order);
        waterCoalOrderRepository.save(order);
        res[0] = "success";
        res[1] = alipayService.pay(alipayOrder) + "," + outTradeNo;
        return res;
    }

    public String[] wxPreCreate(String itemId, String itemName, String address, String rechargeAmount, String account, int type, Long userId, String ip) {
        String[] res = new String[2];
        User one = userRepository.findOne(userId);
        if (one == null) {
            throw new UserException("用户不存在", 202);
        }
        String orderType = "";
        switch (type) {
            case AlipayOrder.TYPE_WATER:
                orderType = WaterCoalOrder.TYPE_WATER;
                break;

            case AlipayOrder.TYPE_ELECTRIC:
                orderType = WaterCoalOrder.TYPE_ELECTRIC;
                break;

            case AlipayOrder.TYPE_COAL:
                orderType = WaterCoalOrder.TYPE_COAL;
                break;

            default:
                throw new UserException("类型错误", 303);
        }
        String outTradeNo = "zyt" + userId + System.currentTimeMillis()   //添加userId
                + (long) (Math.random() * 10000000L);
        WxPayOrder wxPayOrder = publicService.generateWxpayOrder(one, itemName, ip, rechargeAmount, outTradeNo, type);
        wxPayOrderRepository.save(wxPayOrder);

        WaterCoalOrder order = new WaterCoalOrder();
        order.setRechargeAccount(account);
        order.setAddress(address);
        order.setItemId(itemId);
        order.setOutTradeNo(outTradeNo);
        order.setItemName(itemName);
        order.setUserId(userId);
        order.setPayType(BaseQmOrder.PAY_TYPE_WXPAY);
        order.setSaleAmount(rechargeAmount);
        order.setType(orderType);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        order.setOrderTime(sdf.format(new Date()));
        order.setPayState("0");  //这里修改其状态。
        order.setPayResult(BaseQmOrder.STATUS_INIT);
        if (!publicService.querySum(rechargeAmount)) {
            order.setFailReason("直销商余额不足,取消支付宝预下单");
            waterCoalOrderRepository.save(order);
            res[0] = "fail";
            res[1] = "直销商余额不足,取消支付宝预下单";
            return res;
        }
        publicService.setBaseOrderType(order);
        waterCoalOrderRepository.save(order);
        res[0] = "success";
        res[1] = wxPayService.pay(wxPayOrder) + "," + outTradeNo;
        return res;
    }


    public String pay(String outTradeNo) {
        WaterCoalOrder order = waterCoalOrderRepository.findByOutTradeNo(outTradeNo);
        //执行千米消费流程
        logger.error("水电煤order={}", order);
        BmDirectRechargeLifeRechargePayBillRequest req = new BmDirectRechargeLifeRechargePayBillRequest();
        req.setItemId(order.getItemId());
        req.setItemNum(order.getSaleAmount());
        req.setRechargeAccount(order.getRechargeAccount());
        req.setOuterTid(order.getOutTradeNo());
        req.setCallback(publicService.getBmCallbackUrl());
        try {
            BmDirectRechargeLifeRechargePayBillResponse response = publicService.execute(req);
            logger.error("water coal pay response.isSuccess = {}", response.isSuccess());
            if (!response.isSuccess()) {
                //记录失败原因    //退款也可以抽离出来到公共类里面。需要将其抽离出来。
                order.setFailReason(response.getSubMsg());
                order.setPayResult(BaseQmOrder.STATUS_FAIL);
                waterCoalOrderRepository.save(order);
                if (order.getPayType() == BaseQmOrder.PAY_TYPE_ALIPAY) {
                    AlipayOrder byOutTradeNo = alipayOrderRepository.findByOutTradeNo(outTradeNo);
                    byOutTradeNo.setRefundReason(response.getSubMsg());
                    return alipayService.reFund(byOutTradeNo);
                } else if (order.getPayType() == BaseQmOrder.PAY_TYPE_WXPAY) {
                    WxPayOrder wxPayOrder = wxPayOrderRepository.findByOutTradeNo(outTradeNo);
                    wxPayOrder.setRefundReason(response.getSubMsg());
                    return wxPayService.refund(wxPayOrder);
                }
            }
            publicService.parseResponse(order, response.getOrderDetailInfo());
            waterCoalOrderRepository.save(order);
        } catch (ApiException e) {
            order.setFailReason(e.getMessage());
            order.setPayResult(BaseQmOrder.STATUS_FAIL);
            waterCoalOrderRepository.save(order);
            if (order.getPayType() == BaseQmOrder.PAY_TYPE_ALIPAY) {
                AlipayOrder byOutTradeNo = alipayOrderRepository.findByOutTradeNo(outTradeNo);
                byOutTradeNo.setRefundReason(e.getMessage());
                return alipayService.reFund(byOutTradeNo);
            } else if (order.getPayType() == BaseQmOrder.PAY_TYPE_WXPAY) {
                WxPayOrder wxPayOrder = wxPayOrderRepository.findByOutTradeNo(outTradeNo);
                wxPayOrder.setRefundReason(e.getMessage());
                return wxPayService.refund(wxPayOrder);
            }
            e.printStackTrace();
            throw new UserException("付款失败", 202);
        }
        return "error";
    }

    class AccountInfo {
        private String customerAddress;
        private String payAmount;
        private String customerName;

        public String getCustomerAddress() {
            return customerAddress;
        }

        public void setCustomerAddress(String customerAddress) {
            this.customerAddress = customerAddress;
        }

        public String getPayAmount() {
            return payAmount;
        }

        public void setPayAmount(String payAmount) {
            this.payAmount = payAmount;
        }

        public String getCustomerName() {
            return customerName;
        }

        public void setCustomerName(String customerName) {
            this.customerName = customerName;
        }
    }

}
